package org.magnerfuller.imtoolkit.server.session;

import org.magnerfuller.imtoolkit.util.Hose;
import org.magnerfuller.imtoolkit.server.session.event.SessionEvent;
import org.magnerfuller.imtoolkit.server.session.event.listener.SessionEventListener;
import org.magnerfuller.imtoolkit.server.session.medium.SessionMedium;
import org.magnerfuller.imtoolkit.server.service.ServiceBackend;

import java.io.*;
import java.util.Vector;

public class Session extends Thread {

  public static final int BUFF_SIZE = 256;

  protected ServiceBackend backend;

  protected SessionMedium sessionMedium;
  
  protected Vector<SessionEventListener> listeners;

  public Session(ServiceBackend backend, SessionMedium sessionMedium) {
    super();

    this.backend = backend;
    this.sessionMedium = sessionMedium;
    
    listeners = new Vector<SessionEventListener>();
  }

  public void run() {

    backend.start();
    
    while(backend.getInputStream() == null || backend.getOutputStream() == null) {}

    Hose frontToBack;
    Hose backToFront;

    try {
      frontToBack = new Hose(sessionMedium.getInputStream(),
                             backend.getOutputStream(),
                             BUFF_SIZE);

      backToFront = new Hose(backend.getInputStream(),
                             sessionMedium.getOutputStream(),
                             BUFF_SIZE);
      backToFront.start();
      frontToBack.start();

      backend.join();
      
    } catch(IOException e) {
      e.printStackTrace();
    } 
    catch(InterruptedException e) {
      e.printStackTrace();
    }

    _fireSessionEvent(new SessionEvent(this, SessionEvent.SESSION_TERMINATED_SUCCESS));
  }
  
  protected void _fireSessionEvent(SessionEvent e) {
    for(SessionEventListener listener : listeners) {
      listener.sessionEventOccurred(e);
    }
  }
  
  public void addSessionEventListener(SessionEventListener l) {
    listeners.add(l);
  }
  
  public boolean removeSessionEventListener(SessionEventListener l) {
    return listeners.remove(l);
  }
  
  public String toString() {
    String str = "ServiceBackend: " + backend.getClass().getSimpleName()
      + "  SessionMedium: " + sessionMedium.getClass().getSimpleName();
      return str;
  }
}
